package template;

import java.awt.*;
import java.awt.event.*;
import java.util.*;

import objects.*;
import physics.*;
import physics.Vector;
import assets.*;


public class Handler implements KeyListener 
{

	private float SCALAR_MULTIPLIER = 5;
	boolean run = true;
	double prevTime, curTime;
	double prevXDist, curXDist, prevYDist, curYDist;
	
	public Screen getScreen() {
		return screen;
	}

	public void setScreen(Screen screen) {
		this.screen = screen;
	}

	Screen screen;
	ArrayList<BasicShape> objects = new ArrayList<BasicShape>();

	private static final DisplayMode possibleModes[] = {
		new DisplayMode(1360, 768, 32, 0),
		new DisplayMode(800, 600, 32, 0),
		new DisplayMode(800, 600, 24, 0),
		new DisplayMode(800, 600, 16, 0),
		new DisplayMode(640, 480, 32, 0),
		new DisplayMode(640, 480, 24, 0),
		new DisplayMode(640, 480, 16, 0),
		
	};
	///////////////////////////////////////////////////////////////////////////
	public void Inititialize() 
	{
		// .. This is where I'd imagine we load images(sprites) and set any static values
		Window window = screen.getFullScreenWindow();
		addMouse(window);
		window.addKeyListener(this);
	
	}	
	
	public void Run()
	{

		screen = new Screen();
		try
		{
			DisplayMode displayMode = screen.FindCompatibleMode(possibleModes); // this is where we find our screen
			screen.setFullScreen(displayMode);
			Inititialize();
			gameLoop.run(); // Coded in here is everything that changes(logic, redrawing, etc...)
		}
		finally 
		{
			screen.RestoreScreen();
		}
		
	}
	
	Runnable gameLoop = new Runnable() 
	{
		Draw drawObjects = new Draw();
		PhysXProcessor physics = new PhysXProcessor();
		@Override
		public void run() 
		{
			// TODO Auto-generated method stub
			GameLoop();
		}
		
		public void GameLoop()
		{
	
			while (run) // For now we can manually tell the game to stop using esc key or something
			{
				try 
				{
					Graphics2D graphics = screen.getGraphics();
				
					if (objects.size() > 0)
					{	
						graphics.clearRect(0, 0, (int) screen.getWidth(), (int) screen.getHeight());
						physics.handleEvents(objects);
						drawObjects.drawObjects(objects, graphics);	
					}
					else
						graphics.clearRect(0, 0, screen.getWidth(), screen.getHeight());

				
					graphics.dispose(); // garbage
					screen.update();
					Thread.sleep(50);
				} catch (Exception exception) {}
		    }
	    }
	};
	public void stop() { run = false; }

	@Override
	public void keyPressed(KeyEvent event) 
	{
		// TODO Auto-generated method stub
		int key = event.getKeyCode();
		if (key == KeyEvent.VK_ESCAPE)
			stop();
	
			
		
	}

	@Override
	public void keyReleased(KeyEvent event) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyTyped(KeyEvent event) {
		// TODO Auto-generated method stub
		
	}
	
	private void addMouse(Window window) 
	{
		window.addMouseListener(new MouseAdapter()
		{
			Vector mouseVector = new Vector();
			public void mousePressed(MouseEvent mouseEvent)
			{
			
				currentValues(mouseEvent);
				objects.add(new BasicShape("Circle", new Vector(mouseEvent.getX(), mouseEvent.getY()), 20, findMouseVector()));
				previousValues(mouseEvent);
				
			}
			
			private void currentValues(MouseEvent mouseEvent)
			{
				curTime = System.currentTimeMillis();
				curXDist = mouseEvent.getX();
				curYDist = mouseEvent.getY();
			}
			
			private void previousValues(MouseEvent mouseEvent)
			{
				prevTime = System.currentTimeMillis();
				prevXDist = mouseEvent.getX();
				prevYDist = mouseEvent.getY();
			}
			
			private Vector findMouseVector()
			{
				mouseVector.setCoordinates(((curXDist - prevXDist) * SCALAR_MULTIPLIER) / (curTime - prevTime),
						                   ((curYDist - prevYDist) * SCALAR_MULTIPLIER) / (curTime - prevTime));
				
				return mouseVector;
			}

	     });
	}


}
